package com.gonsin.gview.logic.aspect;

import com.gonsin.gview.annotations.data.GDataChanged;
import com.gonsin.gview.logic.services.GViewClientServiceImpl;
import com.gonsin.gview.logic.services.GViewDataServiceImpl;
import com.gonsin.gview.logic.utils.GonsinUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Order(0)
@Slf4j
@Component
public class GDataChangedAspect {

    @Autowired private GViewClientServiceImpl clientService;
    @Autowired private GViewDataServiceImpl dataService;


    @Pointcut("" +
            "execution(@com.gonsin.gview.annotations.data.GDataChanged * *(..))" +
            "")
    public void dataChanged() {
    }

    @Around("dataChanged()")
    public Object after(ProceedingJoinPoint point) throws Throwable {

        Object result = point.proceed();

        try {
            MethodSignature joinPointObject = (MethodSignature) point.getSignature();
            Method method = joinPointObject.getMethod();
            GDataChanged dataChanged = method.getAnnotation(GDataChanged.class);
            String[] dataSourceNames = dataChanged.value();


            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if(attributes == null){
                return result;
            }
            HttpServletRequest request = attributes.getRequest();
            if(request == null){
                return result;
            }

            String edificeKey = GonsinUtils.getEdificeKey(request);
            if(StringUtils.isEmpty(edificeKey)){
                return result;
            }

            for(String source : dataSourceNames){
                try {
                    dataService.notifyDataSourceChanged(edificeKey, source);
                } catch (Exception ex){
                    log.error(ex.toString(), ex);
                }
            }
        } finally {
            return result;
        }

    }

}
